﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ClassLibrary1.entity;
using System.IO;
using System.Threading;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    public class CProgram
    {
        public static int indic=0;

        public static Dictionary<string, Action<string[]>> commands = new Dictionary<string, Action<string[]>> { 
        {"add", add}, {"delete", delete}, {"update", update}, {"list", list}};

        public static Dictionary<string, Type> types = new Dictionary<string, Type> {
        {"car", typeof(Car)}, {"booking", typeof(Booking)}, {"cargo", typeof(Cargo)}, {"client", typeof(Client)}, {"driver", typeof(Driver)}, {"insurance", typeof(Insurance)},};

        public static void ReadEntity()
        {
            Data.entity.Clear();
            StreamReader reader = new StreamReader("objects.txt");
            string s;
            string[] ss;
            int I = 0;
            while (!reader.EndOfStream)
            {
                I++;
                s=reader.ReadLine();
                ss = s.Split(' ');
                try
                {
                    RunCommand(new String[] { "add", ss[0], ss[1] });
                }
                catch (Exception) { }
            }
            reader.Close();
            indic = I;
            reader = new StreamReader("objects.txt");
            while (!reader.EndOfStream)
            {
                RunCommand(("update" + " " + reader.ReadLine()).Split(' '));
                Thread.Sleep(400);
            }
            reader.Close();
        }

        public static void WriteEntity() 
        {
            StreamWriter writer = new StreamWriter("objects.txt");
            indic = Data.entity.Count;
            foreach (BaseEntity o in Data.entity) 
            {
                writer.WriteLine(o.Write());
                Thread.Sleep(400);
            }
            writer.Close();
        }

        public static void RunCommand(string[] args)
        {
            if (args.Length > 1)
            {
                try
                {
                    commands[args[0]](args.Skip(1).ToArray());
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
        }

        public static void add(string[] args)
        {

            var entityType = types[args[0].ToLower()];
            try
            {
                BaseEntity e = (BaseEntity)Activator.CreateInstance(entityType, args.Skip(1).ToArray());
                if(e.id!=0) Data.entity.Add(e);
            }
            catch (Exception) { }
                
            
            
            
        }

        public static void delete(string[] args)
        {
            try
            {
                var entity = Data.entity.FirstOrDefault(item => item.GetType() == types[args[0].ToLower()] && item.id == int.Parse(args[1]));
                if (entity != null)
                {
                    entity.Delete();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
}

        public static void update(string[] args)
        {
            try
            {
                var entity = Data.entity.FirstOrDefault(item => item.GetType() == types[args[0].ToLower()] && item.id == int.Parse(args[1]));
                if (entity != null)
                {
                    entity.Upd(args.Skip(2).ToArray());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

       public static void list(string[] args)
        {
            try
            {
                var entity = Data.entity.FindAll(item => item.GetType() == types[args[0].ToLower()]);
                if (entity != null)
                {
                    foreach (BaseEntity o in entity)
                    {
                        Console.WriteLine(o.Show());
                    }
                }
            }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }

       public static void Spravka() 
        {
            foreach (string i in commands.Keys) Console.WriteLine(i);
            
            var entityType = Data.types;
            foreach (var y in entityType)
            {
                BaseEntity t = (BaseEntity)Activator.CreateInstance(y);
                Console.WriteLine(t.Spravka());
            }
            Console.WriteLine("-------------------------");
        }

       public static void Indicator(Thread t) 
        { 
            while (t.IsAlive)
            {
                Console.Write(".");
                Thread.Sleep(200);
            }
        }

        public static void WriteXml()
        {
            StreamWriter writer = new StreamWriter("data.xml");
            try
            {
                XmlSerializer x = new XmlSerializer(typeof(BaseEntity[]), types.Values.ToArray());
                x.Serialize(writer, Data.entity.ToArray());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                writer.Close();
            }
        }
        public static void LoadXml()
        {
            StreamReader reader = new StreamReader("data.xml");
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(BaseEntity[]), types.Values.ToArray());
                Data.entity.Clear();
                Data.entity.AddRange((BaseEntity[])serializer.Deserialize(reader));
            }
            catch (Exception)
            {
            }
                finally
                {
                    reader.Close();
                }
        }

        static void Main(string[] args)
        {
           Spravka();

            Thread t = new Thread(ReadEntity);
            t.Start();
            Indicator(t);
            Console.WriteLine();
            
            /*string s = Console.ReadLine();
            while (!s.Equals("stop")) 
            {
                args = s.Split(' ');
                RunCommand(args);
                s = Console.ReadLine();
            }

            WriteEntity();
            Console.ReadKey();*/

           
           // WriteXml();
           LoadXml();

        }


    }
}
